Skip to content

feat(desktop): give page links their own click tiers in Files & Editor - #7962

Merged
saddlepaddle merged 2 commits into
mainfrom
saddlepaddle/page-hotkey-settings-5646d50b
Sep 30, 2026
Merged

saddlepaddle merged 2 commits into
mainfrom
saddlepaddle/page-hotkey-settings-5646d50b

Conversation

@saddlepaddle

@saddlepaddle saddlepaddle commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Pages had one "Pages" select under Browser, and only the workspace Pages menu read it. Page URLs clicked in terminals, chat, markdown, and page panes fell through to URL links, so pages couldn't open differently from ordinary URLs.

  • pageOpenAction → pageLinks tier map (click / ⇧ / ⌘ / ⌘⇧). Defaults match URL links, so nothing changes until someone edits it.
  • New Files & Editor → Opening pages → Page links section; the Browser "Pages" row is removed.
  • useUrlLinkAction(mode) picks the page or URL map per clicked link. Replaces useTerminalUrlPolicy / useInlineUrlPolicy in the terminal (click + hover label), page panes, TipTap markdown, and MarkdownEditor.
  • Pages menu resolves through the page map and falls back to a split pane when a tier is unbound. "External" now opens the page URL in the system browser (it used to navigate to the in-app /pages/$slug view).
  • A saved pageOpenAction choice is not carried over; the setting shipped about two weeks ago.

Verification

  • Typecheck, biome, and 283 related tests pass; check:i18n passes with all 16 locales translated.
  • In the dev app over CDP: set Page links ⌘ Click → "Open in new tab" and kept URL links ⌘ → split pane. ⌘-hover in a terminal labels the page link "Open in new tab" and example.com "Open in split pane". ⌘-click opened the page in a new tab and example.com in a split browser pane. Screenshots: https://app.superset.sh/page/page-links-setting-o4ju11
  • Not checked: clicking a page in the Pages menu (the test workspace had no pages yet), and clicking a page link in chat.

Summary by cubic

Gives page links their own click tiers so pages clicked in terminals, chat, markdown, and page panes can open differently from ordinary URLs, which previously fell through to the URL links setting.

  • Adds a Files & Editor → Opening pages → Page links tier map; the Browser "Pages" row is removed.
  • Defaults match URL links, so behavior is unchanged until edited.
  • The saved pageOpenAction setting is not migrated over (it shipped about two weeks ago).
  • "External" in the Pages menu now opens the page URL in the system browser instead of navigating to the in-app /pages/$slug view.
  • The Pages menu falls back to opening a split pane when a tier is unbound.

Written for commit f5deacc. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added configurable page-link behavior for links in the Pages menu, terminals, chat, and other pages.
    • Choose how page links open, including in a split or tab, with options based on click modifiers.
    • Find page-link controls in Files settings under “Opening pages.”
  • Improvements
    • Page links now follow your configured preferences across the workspace, including when clicked in the editor.

Pages had a single "Pages" select under Browser that only the workspace
Pages menu read. Page URLs clicked in terminals, chat, markdown, and page
panes fell through to the URL links tier map, so there was no way to make
pages open differently from ordinary URLs.

- Replace pageOpenAction with a pageLinks tier map (defaults match URL
  links, so behavior is unchanged until edited).
- Add "Opening pages → Page links" to Files & Editor; drop the Browser row.
- useUrlLinkAction picks the page or URL map per clicked link; terminal
  click + hover label, page panes, TipTap markdown, and MarkdownEditor use it.
- Pages menu resolves through the page map, falling back to a split pane
  when a tier is unbound; "external" opens the page URL in the system
  browser.
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: de382e57-e178-4550-88eb-f1994963c07f

📥 Commits

Reviewing files that changed from the base of the PR and between 555b711 and f5deacc.

📒 Files selected for processing (37)
  • apps/desktop/src/renderer/components/MarkdownEditor/MarkdownEditor.tsx
  • apps/desktop/src/renderer/components/MarkdownRenderer/components/TipTapMarkdownRenderer/TipTapMarkdownRenderer.tsx
  • apps/desktop/src/renderer/components/MarkdownRenderer/components/TipTapMarkdownRenderer/resolveLinkClick.ts
  • apps/desktop/src/renderer/hooks/useV2UserPreferences/useV2UserPreferences.ts
  • apps/desktop/src/renderer/lib/clickPolicy/index.ts
  • apps/desktop/src/renderer/lib/clickPolicy/policies/policy.ts
  • apps/desktop/src/renderer/lib/clickPolicy/policies/useInlineUrlPolicy.ts
  • apps/desktop/src/renderer/lib/clickPolicy/policies/usePagePolicy.ts
  • apps/desktop/src/renderer/lib/clickPolicy/policies/useTerminalUrlPolicy.ts
  • apps/desktop/src/renderer/lib/clickPolicy/policies/useUrlLinkAction.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspacePagesMenu/WorkspacePagesMenu.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/PagePane/PagePane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspacePaneOpeners/useWorkspacePaneOpeners.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.ts
  • apps/desktop/src/renderer/routes/_authenticated/settings/browser/components/BrowserSettings/BrowserSettings.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/browser/components/BrowserSettings/components/BrowserLinkSettings/BrowserLinkSettings.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/files/components/FilesSettings/FilesSettings.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts
  • packages/i18n/locales/cs/messages.po
  • packages/i18n/locales/de/messages.po
  • packages/i18n/locales/en/messages.po
  • packages/i18n/locales/es/messages.po
  • packages/i18n/locales/fr/messages.po
  • packages/i18n/locales/id/messages.po
  • packages/i18n/locales/it/messages.po
  • packages/i18n/locales/ja/messages.po
  • packages/i18n/locales/ko/messages.po
  • packages/i18n/locales/nl/messages.po
  • packages/i18n/locales/pl/messages.po
  • packages/i18n/locales/pt-BR/messages.po
  • packages/i18n/locales/ru/messages.po
  • packages/i18n/locales/tr/messages.po
  • packages/i18n/locales/vi/messages.po
  • packages/i18n/locales/zh-CN/messages.po
  • packages/i18n/locales/zh-TW/messages.po
💤 Files with no reviewable changes (3)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
  • apps/desktop/src/renderer/lib/clickPolicy/policies/useInlineUrlPolicy.ts
  • apps/desktop/src/renderer/lib/clickPolicy/policies/useTerminalUrlPolicy.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

Page-opening preferences now use a tier map. URL actions route page links and other URLs through separate policies. The Pages menu, Markdown editors, renderers, and workspace panes use the new action selection. Page-link controls move to Files settings, with updated search text and translations.

Changes

Page link actions

Layer / File(s) Summary
Page-link preferences and action selection
apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.ts, apps/desktop/src/renderer/hooks/useV2UserPreferences/useV2UserPreferences.ts, apps/desktop/src/renderer/lib/clickPolicy/*
Preferences replace the single page-opening action with a tier map. The URL action selector chooses page-link or URL policy based on the URL.
URL action handling in editors and panes
apps/desktop/src/renderer/components/MarkdownEditor/MarkdownEditor.tsx, apps/desktop/src/renderer/components/MarkdownRenderer/components/TipTapMarkdownRenderer/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/{PagePane,TerminalPane}/*
Editors, renderers, and panes pass the click event and URL to the new action selector.
Pages menu navigation and pane placement
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspacePagesMenu/WorkspacePagesMenu.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspacePaneOpeners/useWorkspacePaneOpeners.ts, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
The Pages menu uses a four-tier page policy. It opens external actions through Electron and passes tab or split placement to the pane opener for other actions.
Page-link settings and translations
apps/desktop/src/renderer/routes/_authenticated/settings/{browser,files}/..., apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts, packages/i18n/locales/*/messages.po
Files settings adds an “Opening pages” tier mapper. Browser settings removes its Pages control. Search text and locale entries are updated.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant WorkspacePagesMenu
  participant PagePolicy
  participant ElectronClient
  participant WorkspacePaneOpener
  participant PaneStore
  User->>WorkspacePagesMenu: Select page
  WorkspacePagesMenu->>PagePolicy: Resolve page action
  alt Action is external
    WorkspacePagesMenu->>ElectronClient: Open encoded page URL
  else Action is not external
    WorkspacePagesMenu->>WorkspacePaneOpener: Open page with tab or split placement
    WorkspacePaneOpener->>PaneStore: Store page pane placement
  end
Loading

Suggested reviewers: kitenite

Merge Risk: ⚪ Minimal · up to f5dea

Page links now have independent click preferences across the supported surfaces. No actionable merge-blocking issue is established; the change is mergeable subject to normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to f5dea

External opening remains constrained by URL validation, and menu-generated page URLs stay on the configured website. The main design risk is preference drift: upgrading can change previously customized page gestures to open outside the app. No exploitable vulnerability was established, but compatibility and authorization coverage remain incomplete.

Retained concerns

  • Low · security · inferred: New pageLinks defaults do not preserve the former pageOpenAction choice or inherit customized urlLinks tiers. An upgrade can therefore make a previously in-app or disabled page gesture reach the system browser. This is bounded opening-policy drift, not evidence of arbitrary URL-handler execution.
Security review details

Security Blast Radius

  • inferred — The preference change affects page-link handling within the desktop's organization-scoped local preferences and can move a user-triggered navigation into the system browser. Menu-supplied slugs cannot select another scheme or host through this constructor. Server-side slug authorization and the identity used by the browser remain unverified.

Security Findings and Attack Paths

  • inferred — The supported exposure change is opening-policy drift: a page URL that formerly followed a customized URL tier can now follow the new external default instead. Reaching that branch still requires a link-opening gesture and passes through scheme validation; the reviewed evidence does not establish an authorization bypass or arbitrary OS-handler execution.

Trust Boundaries and Controls

  • observed — Page classification chooses a preference map; it is not authorization. The independent external-opening boundary validates schemes before delegating to the OS. Inline MarkdownEditor has no pane context and sends every non-null action to that boundary, so an in-app placement preference is not a confinement guarantee on that existing surface.

Resilience and Maintainability Implications

  • observed — Preference assignment inserts complete defaults when the fixed row is absent and otherwise updates only the selected map. Repeating the same assignment is locally idempotent. External-opening failures are caught and reported without a fallback to an unvalidated sink; cross-context write conflicts and durable rollback behavior are not established.

Hardening Proposals

  • proposed — Consider an explicit first-upgrade migration that preserves prior non-external choices, with a defined precedence between the old page preference and customized URL tiers. Include downgrade and interrupted-persistence behavior so compatibility changes do not silently restore external opening.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 17 files. (17 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title uses conventional commit format and clearly summarizes the main change: separate click tiers for page links in Files and Editor.
Description check ✅ Passed The description explains the problem, implementation, user-visible changes, testing performed, screenshots, and known untested areas. It omits the template checklist and uses Summary and Verification …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 17 files. (17 skipped: 17 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@expo

expo Bot commented Sep 30, 2026

Copy link
Copy Markdown

No installed development build can load this pull request as an update: its native fingerprint is 7084d376924a and no development build has it. Add the mobile-build label to build one.

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

@saddlepaddle
saddlepaddle merged commit 3049a31 into main Sep 30, 2026
22 checks passed
@saddlepaddle
saddlepaddle deleted the saddlepaddle/page-hotkey-settings-5646d50b branch September 30, 2026 03:44
Kitenite added a commit that referenced this pull request Oct 1, 2026
* docs: weekly update for PRs merged 2026-09-23 to 2026-09-30

Source of truth: live Notion SOP "Weekly Docs Update (automation SOP)".
Window: merged:>=2026-09-23 (139 PRs). PRs through the morning of 09-23
were covered by #7771.

Changes
- Pages: no auto-open on publish (#7790); page links and URL links split
  into their own settings (#7916, #7962, #7946); Listening agents menu with
  per-row stop and Add listening agent (#7724, #7820, #7919); globe on the
  Share button (#7766); Report on public pages (#7886); agents offer a page
  (#7759). Files: pages.mdx, cli/cli-reference.mdx.
- Settings moves: Links replaced by Browser and Files & Editor (#7916,
  #7962). Files: editor.mdx, terminal-integration.mdx, customization.mdx.
- Editor: inline rename and drag to move (#7692), Auto Save (#7693, #7916),
  open and save files outside the workspace (#7897, #7982), Copy as Markdown
  (#7591), per-pane error screen (#7983). File: editor.mdx.
- Terminal copy follows Ghostty's whitespace rules (#7868).
  File: terminal-integration.mdx.
- Agents: UFO (#7898); GPT-6 Astra, Sonnet 5.5, retiring GPT-5.5, retired
  GPT-5.4/5.3 Codex (#7783, #7894, #7935). Files: agent-integration.mdx,
  cli/cli-reference.mdx.
- Host: superset start --daemon --auto-update and update-lock permission
  errors (#7735, #7952). Files: cli/host-server.mdx, cli/cli-reference.mdx.
- Removed the mcp CLI section and the Connected Service Plugins section:
  #7776 made plugins/mcp internal, the Plugins page is staff-flagged, and
  apps/docs/AGENTS.md keeps internal commands out. Files: skills.mdx,
  cli/cli-reference.mdx.
- Slack page unfurls and details panel (#7817, #7821, #7914, #7957).
  File: use-with-slack.mdx.
- Workspaces: instant creation with background naming (#7518); recoverable
  project deletion (#7896). File: workspaces.mdx.
- Shortcuts: prev/next workspace includes Pinned and wraps (#7851); ⌘B
  collapses the sidebar to a rail (#7964). File: keyboard-shortcuts.mdx.
- Ship controls and open-in button moved to the right sidebar strip (#7958).
  Files: diff-viewer.mdx, use-with-ide.mdx.

Deliberately skipped
- Cloud workspaces/environments/sandboxes (flag-gated, AGENTS.md rule):
  #7784 #7795 #7824 #7840 #7844 #7845 #7847 #7849 #7850 #7858 #7861 #7863
  #7874 #7911 #7913 #7918 #7922 #7931 #7932 #7937 #7956 #7961 #7969 #7981
  #7637 #7794 #7789 #7838 (its CLI docs already shipped in the PR).
- Staff-only plugins: #7912 Sentry plugin, #7716, #7727, #7955.
- Already documented in their own PRs: #7917, #7921.
- Removed feature never documented: #7796 Google Calendar triggers.
- Agents chip remove/revert/default-off, never documented: #7870 #7871 #7872.
- Billing/backend policy with no docs surface: #7947, #7812, #7786, #7792,
  #7798, #7761, #7948, #7949, #7951, #7827.
- Reverted security trio: #7828 #7829 #7830 (reverted by #7834).
- Fixes restoring expected behavior: #7683 #7696 #7707 #7743 #7751 #7756
  #7764 #7765 #7781 #7788 #7791 #7823 #7825 #7833 #7837 #7852 #7857 #7860
  #7864 #7865 #7869 #7873 #7897-covered #7903 #7938 #7980 #7943 #7964-chrome.
- Mobile (no docs page): #7746 #7747 #7748 #7749 #7750 #7782 #7793 #7810
  #7814 #7816 #7889 #7968.
- Marketing, internal docs, CI, version bumps: #7651 #7744 #7752 #7771 #7774
  #7776-infra #7777 #7785 #7811 #7818 #7822 #7826 #7834 #7884 #7885 #7895
  #7909 #7933 #7934 #7942 #7944 #7965 #7966.

Validation: bun run --cwd apps/docs typecheck, bun run lint:fix,
bun run lint (exit 0), Vale on 13 changed files (0 errors, 0 warnings),
git diff --check.

* chore: log weekly docs update follow-ups

* docs: tighten review findings in the weekly update

Only the page creator can stop or add listening agents. On focus change also
saves on window blur, and Auto Save pauses on conflicts. Taken-down pages do
not unfurl. Model picker coverage matches agent-models.ts.

This branch was previously deployed

1 inactive deployment
preview — f5deacc8 Deployed Sep 30, 2026 by saddlepaddle via Deploy API #10606
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant